package com.group56.view.coachend.schedule_module;

import com.group56.model.dao.Impl.ScheduleDAOImpl;
import com.group56.model.dao.ScheduleDAO;
import com.group56.utils.FXMLViewHandler;
import com.group56.view.ViewController;
import com.group56.view.userend.schedule_module.ScheduleListController;
import com.group56.viewmodel.dto.ScheduleDTO;
import javafx.application.Platform;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.binding.ObjectExpression;
import javafx.beans.property.*;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableObjectValue;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.effect.Effect;
import javafx.scene.effect.Glow;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.concurrent.Callable;


public class ScheduleRectController implements ViewController {
    public StackPane pane;
    public Rectangle rect;//TODO: 抽一个Rectangle封装类
    public Text text;//optional text shown above rect

    //schedule-info modal stage
    public StringProperty date = new SimpleStringProperty();
    public StringProperty time = new SimpleStringProperty();
    public StringProperty cname = new SimpleStringProperty();
    public StringProperty cage = new SimpleStringProperty();
    public StringProperty cheight = new SimpleStringProperty();
    public StringProperty cgoal = new SimpleStringProperty();
    public StringProperty cweight = new SimpleStringProperty();

    private ObjectProperty<STATUS> status;
    private final double height = 49.0;
    private final double width = 100.0;
    private ScheduleInfoController modalController;
    private CoachScheduleController parentController;
    private ScheduleDTO scheduleDTO;

    //TODO:把parentController里从VM拿到的信息注入进来
    public void inject(){

    }

    @Override
    public void bind() {
        ViewController.super.bind();
    }

    @Override
    public void registerToMediator() {

    }

    @Override
    public Parent getView() {
        return pane;
    }

    public enum STATUS{
        BOOKED("booked",Color.rgb(145,255,203)),//"#91ffcb"
        UNBOOKED("unbooked", Color.rgb(250, 238, 167)),//"#faeea7"
        AVAILABLE("available",Color.rgb(168, 211, 252)),//"#28d3fc"
        UNAVAILABLE("unavailable",Color.rgb(255, 128, 128)),//"#ff8080"
        ;
        private final String status;
        private final Color color;

        STATUS(String status, Color color) {
            this.status = status;
            this.color = color;
        }
        public String getStatus(){
            return status;
        }
        public Color getColor() {
            return color;
        }
    }
    public ScheduleRectController(STATUS status) {
        this.rect = new Rectangle(width,height);
        this.status = new SimpleObjectProperty<>(status);
        this.pane = new StackPane();
        try {
            this.modalController = FXMLViewHandler.getController("/coach/ScheduleInfo.fxml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        rect.setArcHeight(5);
        rect.setArcWidth(5);
        rect.setOpacity(1);
        rect.setCursor(Cursor.HAND);
        rect.setEffect(new Glow());
        rect.setStroke(Color.BLACK);
        rect.setStrokeWidth(1);
        pane.getChildren().add(rect);
        initPane();
    }
    public ScheduleRectController(ScheduleDTO scheduleDTO, STATUS status){
        this.scheduleDTO = scheduleDTO;
        this.rect = new Rectangle(width,height);
        this.status = new SimpleObjectProperty<>(status);
        this.status.bindBidirectional(scheduleDTO.statusProperty());
        this.pane = new StackPane();
        try {
            this.modalController = FXMLViewHandler.getController("/coach/ScheduleInfo.fxml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        rect.setArcHeight(5);
        rect.setArcWidth(5);
        rect.setOpacity(1);
        rect.setCursor(Cursor.HAND);
        rect.setEffect(new Glow());
        rect.setStroke(Color.BLACK);
        rect.setStrokeWidth(1);
        pane.getChildren().add(rect);
        initPane();
//        onchange();
    }
    //further initialize the Rectangle and StackPane according to its current status
    public void onchange(){
        status.addListener(new ChangeListener<STATUS>() {
            @Override
            public void changed(ObservableValue<? extends STATUS> observableValue, STATUS status, STATUS t1) {
                initPane();
            }
        });
    }
    public void initPane(){
        rect.fillProperty().set(status.get().getColor());
        //        ObjectBinding<ObjectProperty<Paint>> binding = new ObjectBinding<ObjectProperty<Paint>>() {
//            @Override
//            protected ObjectProperty<Paint> computeValue() {
//                return null;
//            }
//        }
//        rect.fillProperty().bindBidirectional(scheduleDTO.statusProperty().get().color);
//        rect.setFill(status.getColor());
        if(this.status.get()==STATUS.AVAILABLE) {
            rect.setOnMouseClicked(mouseEvent -> {
                this.status.set(STATUS.UNAVAILABLE);
                initPane();
            });
        }
        if(this.status.get()==STATUS.UNAVAILABLE) {
            rect.setOnMouseClicked(mouseEvent -> {
                this.status.set(STATUS.AVAILABLE);
                initPane();
            });
        }
        if(this.status.get()==STATUS.UNBOOKED) {
            rect.setOnMouseClicked(mouseEvent -> {
                Alert alert = new Alert(Alert.AlertType.WARNING);
                alert.setContentText("please arrange your time ahead of 3 days");
                alert.setHeaderText("you cannot modify the schedules within 3 days");
                alert.show();
            });
        }
        if(this.status.get()==STATUS.BOOKED) {
            this.cname.bindBidirectional(scheduleDTO.getCustomerDTO().nameProperty());
            this.cage.bindBidirectional(scheduleDTO.getCustomerDTO().ageProperty());
            this.cgoal.bindBidirectional(scheduleDTO.getCustomerDTO().goalProperty());
            this.date.bindBidirectional(scheduleDTO.dateProperty());
            this.time.bindBidirectional(scheduleDTO.timeProperty());
            this.cheight.bindBidirectional(scheduleDTO.getCustomerDTO().heightProperty());
            this.cweight.bindBidirectional(scheduleDTO.getCustomerDTO().weightProperty());
            text = new Text(this.cname.getValue());
            text.setCursor(Cursor.HAND);
            pane.getChildren().add(text);
            rect.setOnMouseClicked(mouseEvent -> {
                try {
                    Stage stage = new Stage();
                    FXMLLoader fxmlLoader = new FXMLLoader();
                    fxmlLoader.setLocation(FXMLViewHandler.class.getResource("/coach/ScheduleInfo.fxml"));
                    Parent root = fxmlLoader.load();
                    ScheduleInfoController scheduleInfoController = fxmlLoader.getController();
                    scheduleInfoController.init(date.get(), time.get(), cname.get(), cage.get(), cheight.get(), cweight.get(), cgoal.get());
                    FXMLViewHandler.putViewInStage(stage, root, "schedule info");
                    stage.show();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
    public Rectangle getRect() {
        return rect;
    }
    public StackPane getPane() {
        return pane;
    }
    public void setReadOnly(){
        rect.setOnMouseClicked(null);
    }
}
